package com.transaction.test.local.mybatis.service.impl;

import com.transaction.test.local.mybatis.bean.User1;
import com.transaction.test.local.mybatis.bean.User2;
import com.transaction.test.local.mybatis.service.TransactionPropagationExample;
import com.transaction.test.local.mybatis.service.User1Service;
import com.transaction.test.local.mybatis.service.User2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author mdl
 * @date 2019/12/19
 */
@Service
public class TransactionPropagationExampleImpl implements TransactionPropagationExample {
    @Autowired
    private User1Service user1Service;

    @Autowired
    private User2Service user2Service;

    @Override
    public void truncated() {
        user1Service.truncate();
        user2Service.truncate();
    }

    @Override
    public void outerNoTransaction_Required_Required() {
        User1 user1 =new User1();
        user1.setName("张三");
        user1Service.addRequired(user1);

        User2 user2 =new User2();
        user2.setName("李四");
        user2Service.addRequired(user2);

        throw new RuntimeException();
    }

    @Override
    public void outerNoTransaction_Required_RequiredException() {
        User1 user1 =new User1();
        user1.setName("张三");
        user1Service.addRequired(user1);

        User2 user2 =new User2();
        user2.setName("李四");
        user2Service.addRequiredException(user2);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void outerTransaction_Required_Required() {
        User1 user1 =new User1();
        user1.setName("张三");
        user1Service.addRequired(user1);

        User2 user2 =new User2();
        user2.setName("李四");
        user2Service.addRequired(user2);

        throw new RuntimeException();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void outerTransaction_Required_RequiredException() {
        User1 user1 =new User1();
        user1.setName("张三");
        user1Service.addRequired(user1);

        User2 user2 =new User2();
        user2.setName("李四");
        user2Service.addRequiredException(user2);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void outerTransaction_Required_RequiredExceptionTry() {
        User1 user1 =new User1();
        user1.setName("张三");
        user1Service.addRequired(user1);

        User2 user2 =new User2();
        user2.setName("李四");
        try {
            user2Service.addRequiredException(user2);
        } catch (Exception e) {
            System.out.println("try catch 回滚");
        }
    }

    @Override
    public void outerNoTransaction_RequiresNew_RequiresNew() {
        User1 user1=new User1();
        user1.setName("张三");
        user1Service.addRequiresNew(user1);

        User2 user2=new User2();
        user2.setName("李四");
        user2Service.addRequiresNew(user2);
        throw new RuntimeException();
    }

    @Override
    public void outerNoTransaction_RequiresNew_RequiresNewException() {
        User1 user1=new User1();
        user1.setName("张三");
        user1Service.addRequiresNew(user1);

        User2 user2=new User2();
        user2.setName("李四");
        user2Service.addRequiresNewException(user2);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void outerExceptionRequired_Required_RequiresNew_RequiresNew() {
        User1 user1=new User1();
        user1.setName("张三");
        user1Service.addRequired(user1);

        User2 user2=new User2();
        user2.setName("李四");
        user2Service.addRequiresNew(user2);

        User2 user3=new User2();
        user3.setName("王五");
        user2Service.addRequiresNew(user3);
        throw new RuntimeException();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void outerRequired_Required_RequiresNew_RequiresNewException() {
        User1 user1=new User1();
        user1.setName("张三");
        user1Service.addRequired(user1);

        User2 user2=new User2();
        user2.setName("李四");
        user2Service.addRequiresNew(user2);

        User2 user3=new User2();
        user3.setName("王五");
        user2Service.addRequiresNewException(user3);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void outerRequired_Required_RequiresNew_RequiresNewException_Try() {
        User1 user1=new User1();
        user1.setName("张三");
        user1Service.addRequired(user1);

        User2 user2=new User2();
        user2.setName("李四");
        user2Service.addRequiresNew(user2);

        User2 user3=new User2();
        user3.setName("王五");
        try {
            user2Service.addRequiresNewException(user3);
        } catch (Exception e) {
            System.out.println("方法回滚");
        }
    }

    @Override
    public void outerNoTransaction_Nested_Nested() {
        User1 user1 =new User1();
        user1.setName("张三");
        user1Service.addNested(user1);

        User2 user2 =new User2();
        user2.setName("李四");
        user2Service.addNested(user2);

        throw new RuntimeException();
    }

    @Override
    public void outerNoTransaction_Nested_NestedException() {
        User1 user1 =new User1();
        user1.setName("张三");
        user1Service.addNested(user1);

        User2 user2 =new User2();
        user2.setName("李四");
        user2Service.addNestedException(user2);
    }

    @Override
    @Transactional
    public void outerExceptionTransaction_Nested_Nested() {
        User1 user1 =new User1();
        user1.setName("张三");
        user1Service.addNested(user1);

        User2 user2 =new User2();
        user2.setName("李四");
        user2Service.addNested(user2);

        throw new RuntimeException();
    }

    @Override
    @Transactional
    public void outerTransaction_Nested_NestedException() {
        User1 user1 =new User1();
        user1.setName("张三");
        user1Service.addNested(user1);

        User2 user2 =new User2();
        user2.setName("李四");
        user2Service.addNestedException(user2);
    }

    @Override
    @Transactional
    public void outerTransaction_Nested_NestedTry() {
        User1 user1 =new User1();
        user1.setName("张三");
        user1Service.addNested(user1);

        User2 user2 =new User2();
        user2.setName("李四");
        try {
            user2Service.addNestedException(user2);
        } catch (Exception e) {
            System.out.println("方法回滚");
        }
    }

}
